package cn.edu.cuit.elena.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

import cn.edu.cuit.elena.common.Configurable;
import cn.edu.cuit.elena.common.SackConstants;

public class DataSource
{
    private static int MAX_CONNECTIONS = SackConstants.MAX_CONNECTION_NUM;

    private LinkedList<Connection> connections;
    private Configurable dataSourceConfiguration;
    private String url;
    private String userName;
    private String passWord;

    public static DataSource create( Configurable configurable )
    {
        try
        {
            Class.forName( configurable.getProperty( "DB_DRIVER" ) );
            return new DataSource( configurable );
        }
        catch( ClassNotFoundException e )
        {
            throw new DataSourceException( e.getMessage() );
        }
        catch( SQLException e )
        {
            throw new DataSourceException( e.getMessage() );
        }
    }

    private DataSource(Configurable configurable) throws SQLException
    {
        dataSourceConfiguration = configurable;
        url = dataSourceConfiguration.getProperty( "URL" );
        userName = dataSourceConfiguration.getProperty( "USERNAME" );
        passWord = dataSourceConfiguration.getProperty( "PASSWORD" );
        createConnectionPool();
    }

    private void createConnectionPool() throws SQLException
    {
        connections = new LinkedList<Connection>();
        for( int i = 0; i < MAX_CONNECTIONS; i++ )
        {
            connections.add( DriverManager.getConnection( url, userName, passWord ) );
        }
    }

    /**
     * Get connection from connection pool, use <code>synchronized</code> block to guarantee working
     * correctly.
     * */
    public Connection getConnection()
    {
        synchronized( connections )
        {
            if( connections.size() == 0 )
            {
                try
                {
                    connections.add( DriverManager.getConnection( url, userName, passWord ) );
                }
                catch( SQLException e )
                {
                    throw new DataSourceException( e.getMessage() );
                }
            }

            return connections.pop();
        }

    }

    /**
     * Get connection from connection pool, use <code>synchronized</code> block to guarantee working
     * correctly.
     * */
    public void returnConnection( Connection connection )
    {
        synchronized( connections )
        {
            if( connections.size() == MAX_CONNECTIONS )
            {
                try
                {
                    connection.close();
                }
                catch( SQLException e )
                {
                    e.printStackTrace();
                    throw new DataSourceException( e.getMessage() );
                }
                return;
            }

            connections.add( connection );
        }
    }

    public int getDBCode()
    {
        // TODO Auto-generated method stub
        return 0;

    }
}
